// /**
//  * @file esptim.c
//  * @author your name (you@domain.com)
//  * @brief
//  * @version 0.1
//  * @date 2024-06-08
//  *
//  * @copyright Copyright (c) 2024
//  *
//  */

// #include "gptim.h"

// QueueHandle_t queue;

// gptimer_handle_t g_tim = NULL;

// void output_gptime_value(void)
// {
// 	uint64_t count;
// 	ESP_ERROR_CHECK(gptimer_get_raw_count(g_tim, &count)); /* 获取计数值 */
// 	ESP_LOGI("GPTIMER_ALARM", "定时器计数值： %llu", count);
// }

// /**
//  * @brief       初始化通用定时器
//  * @param       counts: 计数值
//  * @param       resolution: 定时器周期，resolution = 1s = 1000000μs（此处，定时器以微秒作为计算单位，）
//  * @retval      无
//  */
// void gptim_int_init(uint16_t counts, uint16_t resolution)
// {
// 	gptimer_config_t g_tim_handle;
// 	gptimer_alarm_config_t alarm_config;
// 	gptimer_event_callbacks_t g_tim_callbacks;

// 	uint64_t count;

// 	/* 配置通用定时器 */
// 	ESP_LOGI("GPTIMER_ALARM", "配置通用定时器"); /* 创建通用定时器句柄 */

// 	g_tim_handle.clk_src = GPTIMER_CLK_SRC_DEFAULT; /* 选择定时器时钟源 */
// 	g_tim_handle.direction = GPTIMER_COUNT_UP;		/* 递增计数模式 */
// 	g_tim_handle.resolution_hz = resolution;		/* 计数器分辨率 */
// 	g_tim_callbacks.on_alarm = gptimer_callback;	/* 注册用户回调函数 */

// 	alarm_config.alarm_count = 1000000; /* 报警目标计数值 */
// 	alarm_config.reload_count = 0;
// 	alarm_config.flags.auto_reload_on_alarm = true; // 开启重加载

// 	ESP_ERROR_CHECK(gptimer_new_timer(&g_tim_handle, &g_tim)); /* 创建新的通用定时器，并返回句柄 */

// 	queue = xQueueCreate(10, sizeof(gptimer_event_t)); /* 创建一个队列，并引入一个事件 */

// 	if (!queue)
// 	{
// 		ESP_LOGE("GPTIMER_ALARM", "创建队列失败"); /* 创建队列失败 */

// 		return;
// 	}

// 	/* 设置和获取计数值 */
// 	ESP_LOGI("GPTIMER_ALARM", "设置计数值");
// 	ESP_ERROR_CHECK(gptimer_set_raw_count(g_tim, counts)); /* 设置计数值 */
// 	ESP_LOGI("GPTIMER_ALARM", "获取计数值");
// 	ESP_ERROR_CHECK(gptimer_get_raw_count(g_tim, &count)); /* 获取计数值 */
// 	ESP_LOGI("GPTIMER_ALARM", "定时器计数值： %llu", count);

// 	/* 注册事件回调函数 */
// 	ESP_ERROR_CHECK(gptimer_register_event_callbacks(g_tim, &g_tim_callbacks, queue)); /* 配置通用定时器回调函数 */

// 	/* 设置报警动作 */
// 	ESP_LOGI("GPTIMER_ALARM", "使能通用定时器");
// 	ESP_ERROR_CHECK(gptimer_enable(g_tim));							 /* 使能通用定时器 */
// 	ESP_ERROR_CHECK(gptimer_set_alarm_action(g_tim, &alarm_config)); /* 配置通用定时器报警事件 */
// 	ESP_ERROR_CHECK(gptimer_start(g_tim));							 /* 启动通用定时器 */
// }

// /**
//  * @brief       定时器回调函数
//  * @param       无
//  * @retval      无
//  */
// bool IRAM_ATTR gptimer_callback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
// {
// 	BaseType_t high_task_awoken = pdFALSE;
// 	queue = (QueueHandle_t)user_data;

// 	/* 从事件数据中检索计数值 */
// 	gptimer_event_t ele = {
// 		.event_count = edata->count_value};

// 	/* 可选：通过操作系统队列将事件数据发送到其他任务 */
// 	xQueueSendFromISR(queue, &ele, &high_task_awoken);

// 	// /* 重新配置报警值 */
// 	// gptimer_alarm_config_t alarm_config = {
// 	// 	.alarm_count = edata->alarm_value + 1000000, /* 在接下来的1秒内报警 */
// 	// };
// 	// gptimer_set_alarm_action(timer, &alarm_config);

// 	/* 返回是否需要在ISR结束时让步 */
// 	return high_task_awoken == pdTRUE;
// }


#include "gptim.h"

/**
 * @函数说明        定时器回调函数
 * @传入参数            
 * @函数返回        
 */
static bool IRAM_ATTR TimerCallback(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
{
    BaseType_t high_task_awoken = pdFALSE;
    //将传进来的队列保存
    QueueHandle_t queue = (QueueHandle_t)user_data;
    
    //从中断服务程序（ISR）中发送数据到队列
    xQueueSendFromISR(queue, &edata->alarm_value, &high_task_awoken);
   
    return (high_task_awoken == pdTRUE);
}

/**
 * @函数说明        定时器初始化配置
 * @传入参数        resolution_hz=定时器的分辨率  alarm_count=触发警报事件的目标计数值
 * @函数返回        创建的定时器回调队列
 */
QueueHandle_t timerInitConfig(uint32_t resolution_hz, uint64_t alarm_count)
{
    //定义一个通用定时器
    gptimer_handle_t gptimer = NULL;

    //创建一个队列
    QueueHandle_t queue = xQueueCreate(10, sizeof(uint64_t)); /* 创建一个队列，并引入一个事件 */
    //如果创建不成功
    if (!queue) {
        ESP_LOGE("queue", "Creating queue failed");
        return NULL;
    }

    //配置定时器参数
    gptimer_config_t timer_config = {
        .clk_src = GPTIMER_CLK_SRC_DEFAULT, //定时器时钟来源 选择APB作为默认选项
        .direction = GPTIMER_COUNT_UP,      //向上计数
        //计数器分辨率(工作频率)以Hz为单位，因此，每个计数滴答的步长等于(1 / resolution_hz)秒
        //假设 resolution_hz = 1000 000
        //1 / resolution_hz = 1 / 1000000 = 0.000001(秒) = 1(微秒) （ 1 tick= 1us ）
        .resolution_hz = resolution_hz, 
    };
    //将配置设置到定时器
    gptimer_new_timer(&timer_config, &gptimer);

    //绑定一个回调函数
    gptimer_event_callbacks_t cbs = {
        .on_alarm = TimerCallback,
    };
    //设置定时器gptimer的 回调函数为cbs  传入的参数为NULL
    gptimer_register_event_callbacks(gptimer, &cbs, queue);

    //使能定时器
    gptimer_enable(gptimer);

    
    //通用定时器的报警值设置 
    gptimer_alarm_config_t alarm_config = {
        .reload_count = 0,  //重载计数值为0 
        .alarm_count = alarm_count, // 报警目标计数值 1000000 = 1s
        .flags.auto_reload_on_alarm = true, //开启重加载
    };
    //设置触发报警动作
    gptimer_set_alarm_action(gptimer, &alarm_config);
    //开始定时器开始工作
    gptimer_start(gptimer);

    return queue;
}
